package com.ld.shieldsb.common.core.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;

import org.jsoup.Connection;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.helper.JsoupUploadConnection;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Whitelist;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.ld.shieldsb.common.core.collections.MapUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 描述: 过滤 HTML 标签中 XSS 代码
 */
@Slf4j
public class JsoupUtil {
    public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36";
    public static final int TIMEOUT_MILLIS = 5 * 1000; // 超时时间，默认5秒
    public static final int TIMEOUT_MILLIS_UPLOAD = 60 * 1000; // 上传超时时间，默认1分钟

    private static String baseUri = "";
    private static final String ERR_MSG = "获取远程内容出错！url:%s,userAgent:%s,timeoutMillis:%s, headers:%s,data:%s,method:%s";
    private static final String ATTR_CLASS = "class";
    /**
     * 使用自带的 none 白名单 只保留标签内文本内容,用于普通输入框输入,可在具体项目中覆盖规则
     * 
     */
    private static final Whitelist WHITELIST_NONE = Whitelist.none();
    /**
     * 属性 relaxed 白名单 用于文本编辑器输入允许的便签有a,b,blockquote,br,caption,cite, code,col,colgroup,dd,div,dl,dt, em,h1,h2,h3,h4,h5,h6,i,img,li,
     * ol,p,pre,q,small,span,strike,strong, sub,sup,table,tbody,td,tfoot,th,thead,tr,u,ul
     * 
     */
    private static final Whitelist WHITELIST = Whitelist.relaxed();

    /** 配置过滤化参数, 不对代码进行格式化 */
    private static final Document.OutputSettings OUTPUT_SETTINGS = new Document.OutputSettings().prettyPrint(false);
    /** 配置过滤化参数, 对代码进行格式化 */
    private static final Document.OutputSettings OUTPUT_SETTINGS_PRETTY = new Document.OutputSettings().prettyPrint(true);
    static {
        // 富文本编辑时一些样式是使用 style 来进行实现的
        // 比如红色字体 style="color:red;"
        // 所以需要给所有标签添加 style 属性
        WHITELIST.addAttributes(":all", "style");
        WHITELIST.addAttributes("pre", ATTR_CLASS); // 代码语言
        WHITELIST.addAttributes("a", "target", "_blank", "download"); // 新窗口打开
        WHITELIST.addAttributes("video", ATTR_CLASS, "controls", "preload", "width", "height", "src"); // 视频
        WHITELIST.addAttributes("source", "src", "type"); // 视频
        WHITELIST.addAttributes("embed", ATTR_CLASS, "pluginspage", "src", "width", "height", "wmode", "play", "loop", "menu",
                "allowscriptaccess", "allowfullscreen"); // 视频
        WHITELIST.addAttributes("span", "class"); //
        WHITELIST.addTags("video", "embed", "span");
        // 移除Protocols设置否则写相对路径不能通过
        WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto"); // 不验证，允许写相对路径
        WHITELIST.removeProtocols("img", "src", "http", "https"); // 不验证，允许写相对路径

        trustEveryone();
    }

    /**
     * 过滤html标签(默认不格式化)
     * 
     * @Title clean
     * @author 吕凯
     * @date 2018年7月2日 上午8:58:11
     * @param content
     *            过滤内容
     * @return String
     */
    public static String clean(String content) {
        return clean(content, false);
    }

    /**
     * 过滤html标签
     * 
     * @Title clean
     * @author 吕凯
     * @date 2018年7月2日 上午8:57:30
     * @param content
     *            过滤内容
     * @param pretty
     *            是否格式化
     * @return String
     */
    public static String clean(String content, boolean pretty) {
        // Jsoup.clean() 方法返回的代码已经被进行格式化, 在标签及标签内容之间添加了 \n 回车符, 如果不需要的话,
        // 可以使用 Jsoup.clean(testHtml, "", whitelist, new Document.OutputSettings().prettyPrint(false)); 进行过滤
        if (pretty) {
            return Jsoup.clean(content, baseUri, WHITELIST, OUTPUT_SETTINGS_PRETTY);
        }
        return Jsoup.clean(content, baseUri, WHITELIST, OUTPUT_SETTINGS);
    }

    /**
     * 清除html标签，用于普通input输入过滤（里面的html标签进行了转移，如>转义为&gt;）
     * 
     * @Title cleanAllHtml
     * @author 吕凯
     * @date 2018年7月2日 上午9:17:44
     * @param content
     * @return String
     */
    public static String cleanAllHtml(String content) {
        return Jsoup.clean(content, baseUri, WHITELIST_NONE, OUTPUT_SETTINGS);
    }

    /**
     * 去除html标签，html特殊字符转换为正常显示的代码，如&gt;显示为>
     * 
     * @Title stripHtml
     * @author 吕凯
     * @date 2018年11月21日 上午10:13:21
     * @param htmlStr
     * @return String
     */
    public static String stripHtml(String htmlStr) {
        return Jsoup.parse(htmlStr).text();
    }

    // ========================= 远程内容(html转换)获取 begin =====================
    /**
     * 获取远程地址的内容(html字符串)
     * 
     * @Title getRemoteContent
     * @author 吕凯
     * @date 2018年11月17日 上午10:26:06
     * @param url
     * @return String
     */
    public static String getRemoteURLContent(String url) {
        return getRemoteURLContent(url, USER_AGENT, TIMEOUT_MILLIS);
    }

    /**
     * 
     * 获取远程地址的内容(html字符串)
     * 
     * @Title getRemoteURLContent
     * @author 吕凯
     * @date 2018年11月17日 上午10:38:44
     * @param url
     * @param userAgent
     * @param timeoutMillis
     *            超时时间，单位毫秒
     * @return String
     */
    public static String getRemoteURLContent(String url, String userAgent, int timeoutMillis) {
        return getRemoteURLContent(url, userAgent, timeoutMillis, null, "get");
    }

    public static String getRemoteURLContent(String url, Map<String, String> data, String method) {
        return getRemoteURLContent(url, USER_AGENT, TIMEOUT_MILLIS, data, method);
    }

    public static String getRemoteURLContent(String url, String userAgent, int timeoutMillis, String method) {
        return getRemoteURLContent(url, userAgent, timeoutMillis, null, method);
    }

    public static String getRemoteURLContent(String url, String userAgent, int timeoutMillis, Map<String, String> data, String method) {
        if (method == null) {
            method = "get";
        }
        Document doc = getRemoteURLDocument(url, userAgent, timeoutMillis, data,
                method.equalsIgnoreCase("post") ? Method.POST : Method.GET);
        if (doc != null) {
            return doc.toString();
        }
        return null;
    }
    // ========================= 远程内容(无html转换)获取 begin =====================

    /**
     * 获取远程地址的内容(原始内容，可能为html也可能为字符串)
     * 
     * @Title getRemoteURLText
     * @author 吕凯
     * @date 2020年7月13日 上午8:30:16
     * @param url
     * @return String
     */
    public static String getRemoteURLText(String url) {
        return getRemoteURLText(url, USER_AGENT, TIMEOUT_MILLIS);
    }

    /**
     * 
     * 获取远程地址的内容(原始内容，可能为html也可能为字符串)
     * 
     * @Title getRemoteURLText
     * @author 吕凯
     * @date 2020年7月13日 上午8:30:31
     * @param url
     * @param userAgent
     * @param timeoutMillis
     *            超时时间，单位毫秒
     * @return String
     */
    public static String getRemoteURLText(String url, String userAgent, int timeoutMillis) {
        return getRemoteURLText(url, userAgent, timeoutMillis, null, "get");
    }

    public static String getRemoteURLText(String url, Map<String, String> data, String method) {
        return getRemoteURLText(url, USER_AGENT, TIMEOUT_MILLIS, data, method);
    }

    public static String getRemoteURLText(String url, String userAgent, int timeoutMillis, String method) {
        return getRemoteURLText(url, userAgent, timeoutMillis, null, method);
    }

    public static String getRemoteURLText(String url, String userAgent, int timeoutMillis, Map<String, String> data, String method) {
        if (method == null) {
            method = "get";
        }
        String text = getRemoteURLText(url, userAgent, timeoutMillis, data, method.equalsIgnoreCase("post") ? Method.POST : Method.GET);
        return text;
    }

    public static String getRemoteURLText(String url, String userAgent, int timeoutMillis, Map<String, String> data) {
        return getRemoteURLText(url, userAgent, timeoutMillis, data, Method.GET);
    }

    public static String getRemoteURLText(String url, Map<String, String> data) {
        return getRemoteURLText(url, USER_AGENT, TIMEOUT_MILLIS, data, Method.GET);
    }

    public static String getRemoteURLText(String url, int timeoutMillis, Map<String, String> data) {
        return getRemoteURLText(url, USER_AGENT, timeoutMillis, data, Method.GET);
    }

    public static String getRemoteURLText(String url, String userAgent, int timeoutMillis, Map<String, String> data, Method method) {
        return getRemoteURLText(url, userAgent, timeoutMillis, null, data, method);
    }

    public static String getRemoteURLText(String url, Map<String, String> headers, Map<String, String> data) {
        return getRemoteURLText(url, headers, data, Method.GET);
    }

    public static String getRemoteURLText(String url, Map<String, String> headers, Map<String, String> data, Method method) {
        return getRemoteURLText(url, USER_AGENT, TIMEOUT_MILLIS, headers, data, method);
    }

    /**
     * 获取原始内容
     * 
     * @Title getRemoteURLText
     * @author 吕凯
     * @date 2020年7月13日 上午8:31:30
     * @param url
     * @param userAgent
     * @param timeoutMillis
     * @param headers
     * @param data
     * @param method
     * @return String
     */
    public static String getRemoteURLText(String url, String userAgent, int timeoutMillis, Map<String, String> headers,
            Map<String, String> data, Method method) {
        try {
            Response response = getResponse(url, userAgent, timeoutMillis, headers, data, method);
            String doc = response.body();
            return doc;
        } catch (Exception e) {
            String errMessage = String.format(ERR_MSG, url, userAgent, timeoutMillis, headers, data, method);
            log.error(errMessage, e);
            return null;
        }
    }
    // =================================== 远程Document获取 begin =========================================

    /**
     * 获取远程rul的Document对象（jsoup包内对象，用于自己解析）
     * 
     * @Title getRemoteURLDocument
     * @author 吕凯
     * @date 2018年11月17日 上午10:48:13
     * @param url
     * @param userAgent
     * @param timeoutMillis
     *            超时时间，单位毫秒
     * @return Document
     */
    public static Document getRemoteURLDocument(String url, String userAgent, int timeoutMillis) {
        return getRemoteURLDocument(url, userAgent, timeoutMillis, null);
    }

    public static Document getRemoteURLDocument(String url, String userAgent, int timeoutMillis, Map<String, String> data) {
        return getRemoteURLDocument(url, userAgent, timeoutMillis, data, Method.GET);
    }

    public static Document getRemoteURLDocument(String url, Map<String, String> data) {
        return getRemoteURLDocument(url, USER_AGENT, TIMEOUT_MILLIS, data, Method.GET);
    }

    public static Document getRemoteURLDocument(String url, int timeoutMillis, Map<String, String> data) {
        return getRemoteURLDocument(url, USER_AGENT, timeoutMillis, data, Method.GET);
    }

    public static Document getRemoteURLDocument(String url, String userAgent, int timeoutMillis, Map<String, String> data, Method method) {
        return getRemoteURLDocument(url, userAgent, timeoutMillis, null, data, method);
    }

    public static Document getRemoteURLDocument(String url, Map<String, String> headers, Map<String, String> data) {
        return getRemoteURLDocument(url, headers, data, Method.GET);
    }

    public static Document getRemoteURLDocument(String url, Map<String, String> headers, Map<String, String> data, Method method) {
        return getRemoteURLDocument(url, USER_AGENT, TIMEOUT_MILLIS, headers, data, method);
    }

    public static Document getRemoteURLDocument(String url, String userAgent, int timeoutMillis, Map<String, String> headers,
            Map<String, String> data, Method method) {
        try {
            Response response = getResponse(url, userAgent, timeoutMillis, headers, data, method);
            Document doc = response.parse();
            return doc;
        } catch (Exception e) {
            String errMessage = String.format(ERR_MSG, url, userAgent, timeoutMillis, headers, data, method);
            log.error(errMessage, e);
            return null;
        }
    }

    /**
     * 根据参数获取Response
     * 
     * @Title getResponse
     * @author 吕凯
     * @date 2020年7月13日 上午8:33:13
     * @param url
     * @param userAgent
     * @param timeoutMillis
     * @param headers
     * @param data
     * @param method
     * @return
     * @throws IOException
     *             Response
     */
    private static Response getResponse(String url, String userAgent, int timeoutMillis, Map<String, String> headers,
            Map<String, String> data, Method method) throws IOException {
        Connection conn = Jsoup.connect(url).userAgent(userAgent).timeout(timeoutMillis);
        if (method != null) { // 默认为get方法
            conn = conn.method(method);
        }
        if (headers != null && !headers.isEmpty()) {
            conn = conn.headers(headers);
        }
        if (data != null && !data.isEmpty()) {
            conn = conn.data(data);
        }
        conn.request().ignoreHttpErrors(true); // 忽略错误继续执行status < 200 || status >= 400的为错误
        Response response = conn.execute();
        return response;
    }

    /**
     * 信任任何站点，实现https页面的正常访问
     * 
     */

    public static void trustEveryone() {
        try {
            // 验证是否相等
            HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> hostname.equalsIgnoreCase(session.getPeerHost()));

            SSLContext context = SSLContext.getInstance("TLSv1.2"); // TLS
            context.init(null, new X509TrustManager[] { new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    //
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            } }, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 获取json格式的返回结果
     * 
     * @Title getRemoteURLJson
     * @author 吕凯
     * @date 2018年12月29日 下午2:54:58
     * @param url
     * @return JSONObject
     */
    public static JSONObject getRemoteURLJson(String url) {
        return getRemoteURLJson(url, USER_AGENT, TIMEOUT_MILLIS);
    }

    /**
     * 获取json格式的返回结果
     * 
     * @Title getRemoteURLJson
     * @author 吕凯
     * @date 2019年6月17日 下午12:03:01
     * @param url
     * @param timeoutMillis
     *            超时秒数
     * @return JSONObject
     */
    public static JSONObject getRemoteURLJson(String url, int timeoutSeconds) {
        return getRemoteURLJson(url, USER_AGENT, timeoutSeconds * 1000);
    }

    /**
     * 获取json格式的返回结果
     * 
     * @Title getRemoteURLJson
     * @author 吕凯
     * @date 2018年12月29日 下午2:54:44
     * @param url
     * @param userAgent
     * @param timeoutMillis
     * @return JSONObject
     */
    public static JSONObject getRemoteURLJson(String url, String userAgent, int timeoutMillis) {
        return getRemoteURLJson(url, userAgent, timeoutMillis, null, null);
    }

    public static JSONObject getRemoteURLJson(String url, String userAgent, int timeoutMillis, Method method) {
        return getRemoteURLJson(url, userAgent, timeoutMillis, null, method);
    }

    public static JSONObject getRemoteURLJson(String url, String userAgent, int timeoutMillis, Map<String, String> data) {
        return getRemoteURLJson(url, userAgent, timeoutMillis, data, null);
    }

    public static JSONObject getRemoteURLJson(String url, int timeoutMillis, Map<String, String> data) {
        return getRemoteURLJson(url, USER_AGENT, timeoutMillis, data, null);
    }

    public static JSONObject getRemoteURLJson(String url, Map<String, String> data) {
        return getRemoteURLJson(url, USER_AGENT, TIMEOUT_MILLIS, data, null);
    }

    public static JSONObject getRemoteURLJson(String url, Map<String, String> headers, Map<String, String> data) {
        return getRemoteURLJson(url, USER_AGENT, TIMEOUT_MILLIS, headers, data, null);
    }

    public static JSONObject getRemoteURLJson(String url, String userAgent, int timeoutMillis, Map<String, String> data, Method method) {
        return getRemoteURLJson(url, userAgent, timeoutMillis, null, data, method);
    }

    public static JSONObject getRemoteURLJson(String url, String userAgent, int timeoutMillis, Map<String, String> headers,
            Map<String, String> data, Method method) {
        try {
//            if (url.startsWith("https")) {
//                trustEveryone();
//            }
            Connection conn = Jsoup.connect(url).userAgent(userAgent).timeout(timeoutMillis).ignoreContentType(true);
            if (method != null) { // 默认为get方法
                conn = conn.method(method);
            }
            if (MapUtils.isNotEmpty(headers)) {
                conn = conn.headers(headers);
            }
            if (MapUtils.isNotEmpty(data)) {
                conn = conn.data(data);
            }
            Response response = conn.execute();
            String body = response.body();
            JSONObject json = JSONObject.parseObject(body);
            return json;
        } catch (Exception e) {
            String errMessage = String.format(ERR_MSG, url, userAgent, timeoutMillis, headers, data, method);
            log.error(errMessage, e);
            return null;
        }
    }

    /**
     * 发送json数据，post方式
     * 
     * @Title sendJson
     * @author 吕凯
     * @date 2018年12月29日 下午3:19:38
     * @param data
     *            发送的数据
     * @param url
     * @param userAgent
     * @param timeoutMillis
     *            超时毫秒数
     * @return JSONObject
     */
    public static JSONObject sendJson(Map<String, Object> data, String url, String userAgent, int timeoutMillis) {
        try {
            Response response = Jsoup.connect(url).userAgent(userAgent).timeout(timeoutMillis).method(Method.POST)
                    .requestBody(JSONObject.toJSONString(data)).header("Content-Type", "application/json").ignoreContentType(true)
                    .execute();
            String body = response.body();
            JSONObject json = JSONObject.parseObject(body);
            return json;
        } catch (Exception e) {
            String errMessage = String.format(ERR_MSG, url, userAgent, timeoutMillis, null, data, "post");
            log.error(errMessage, e);
            return null;
        }
    }

    public static void main(String[] args) {
        Map<String, Object> data = new HashMap<>();
        data.put("code", "91410883MA40XCD77W");
        data.put("name", "1111111");
        data.put("type", "FO");
        data.put("userId", "ce52df59eb1b48d6bad10cba3def58c4");
        data.put("requestSource", "1");
        data.put("subjectId", "");
        data.put("unifiedCode", "11410800733880797M");
        JSONObject obj = sendJson(data, "http://222.187.33.220:5181/credit/service/urp/query", USER_AGENT, 10000);
        System.out.println(obj);
    }

    /**
     * 上传文件
     * 
     * @Title upload
     * @author 吕凯
     * @date 2021年4月16日 下午3:12:19
     * @param data
     *            附件参数
     * @param url
     *            上传url
     * @param fileRequestParam
     *            文件对象参数名称
     * @param file
     *            文件对象
     * @param userAgent
     * @param timeoutMillis
     * @return JSONObject
     */
    public static JSONObject uploadFile(Map<String, String> data, String url, File file, String fileRequestParam, String userAgent,
            int timeoutMillis) {
        // 错误信息
        String errMessage = String.format(ERR_MSG, url, userAgent, timeoutMillis, null, data, "post");
        try (FileInputStream fis = new FileInputStream(file)) {
            return uploadFile(data, url, fis, fileRequestParam, file.getName(), userAgent, timeoutMillis);
        } catch (Exception e) {
            log.error(errMessage, e);
        }
        return null;
    }

    /**
     * 以流上传文件
     * 
     * @Title uploadFile
     * @author 吕凯
     * @date 2021年4月16日 下午3:16:40
     * @param data
     * @param url
     * @param fileRequestParam
     *            文件上传参数名
     * @param inputStream
     *            文件输入流
     * @param fileName
     *            文件名称保存用
     * @param userAgent
     * @param timeoutMillis
     * @return JSONObject
     */
    public static JSONObject uploadFile(Map<String, String> data, String url, InputStream inputStream, String fileRequestParam,
            String fileName, String userAgent, int timeoutMillis) {
        // 错误信息
        String errMessage = String.format(ERR_MSG, url, userAgent, timeoutMillis, null, data, "post");
        // 使用了自定义的上传类
        Connection conn = JsoupUploadConnection.connect(url).userAgent(userAgent).timeout(timeoutMillis).ignoreContentType(true);
        conn.method(Connection.Method.POST);
        conn.header("Content-Type", "multipart/form-data");
//        conn.header("Accept", "*/*").header("Accept-Encoding", "gzip, deflate");
        // conn.proxy("127.0.0.1", 8866); // 代理
//        conn.ignoreHttpErrors(true);
        if (MapUtils.isNotEmpty(data)) {
            conn = conn.data(data);
        }
        conn = conn.data(ImmutableMap.of("1", "1"));
        try {
            conn.data(fileRequestParam, fileName, inputStream);
            Response response = conn.execute();
            String body = response.body();
            JSONObject json = JSONObject.parseObject(body);
            return json;
        } catch (Exception e) {
            log.error(errMessage, e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("", e);
                }
            }
        }
        return null;
    }

    // ==================================== 传递文件的重载方法 ========================================
    public static JSONObject upload(String url, InputStream inputStream, String fileRequestParam, String fileName, String userAgent,
            int timeoutMillis) {
        return uploadFile(null, url, inputStream, fileRequestParam, fileName, userAgent, timeoutMillis);
    }

    public static JSONObject upload(String url, InputStream inputStream, String fileRequestParam, String fileName, String userAgent) {
        return uploadFile(null, url, inputStream, fileRequestParam, fileName, userAgent, TIMEOUT_MILLIS_UPLOAD);
    }

    public static JSONObject upload(String url, InputStream inputStream, String fileRequestParam, String fileName, int timeoutMillis) {
        return uploadFile(null, url, inputStream, fileRequestParam, fileName, USER_AGENT, timeoutMillis);
    }

    public static JSONObject upload(String url, InputStream inputStream, String fileRequestParam, String fileName) {
        return uploadFile(null, url, inputStream, fileRequestParam, fileName, USER_AGENT, TIMEOUT_MILLIS_UPLOAD);
    }

    // ==================================== 传递流的重载方法 ========================================
    public static JSONObject uploadFile(String url, File file, String fileRequestParam, String userAgent, int timeoutMillis) {
        return uploadFile(null, url, file, fileRequestParam, userAgent, timeoutMillis);
    }

    public static JSONObject uploadFile(String url, File file, String fileRequestParam, String userAgent) {
        return uploadFile(null, url, file, fileRequestParam, userAgent, TIMEOUT_MILLIS_UPLOAD);
    }

    public static JSONObject uploadFile(String url, File file, String fileRequestParam, int timeoutMillis) {
        return uploadFile(null, url, file, fileRequestParam, USER_AGENT, timeoutMillis);
    }

    public static JSONObject uploadFile(String url, File file, String fileRequestParam) {
        return uploadFile(null, url, file, fileRequestParam, USER_AGENT, TIMEOUT_MILLIS_UPLOAD);
    }

    // ========================= 远程内容获取 end =====================

    public static String getBaseUri() {
        return baseUri;
    }

    public static void setBaseUri(String baseUriVal) {
        log.warn("baseUri被改变，请注意可能会在过滤标签时产生影响！！！！！！！！！！！！！");
        baseUri = baseUriVal;
    }

    public static Whitelist getWhitelistNone() {
        return WHITELIST_NONE;
    }

    public static Whitelist getWhitelist() {
        return WHITELIST;
    }

}
